Every block in a heap zone, whether allocated or free, has a block header that the Memory Manager uses to find its way around in the zone. Block headers are completely transparent to your application. All pointers and handles to allocated blocks reference the beginning of the block's logical contents, following the end of the header. Similarly, whenever you use a variable of type Size , that variable refers to the number of bytes in the block's logical contents, not including the block header. That size is known as the block's logical size, as opposed to its physical size, the number of bytes it actually occupies in memory, including the header and any unused bytes at the end of the block.
There are two reasons that a block might contain such unused bytes:
There is no Pascal record type defining the structure of block headers because you shouldn't normally need to access them directly. In addition, the structure of a block header depends on whether the block is located in a 24-bit or 32-bit zone.
In a 24-bit zone, a block header consists of 8 bytes, which together make up two long words, as shown in Figure 1 .
Figure 1 A block header in a 24-bit zone
In the first long word, the low-order 3 bytes contain the block's physical size in bytes. Adding this number to the block's address gives the address of the next block in the zone. The first byte of the block header is a tag byte that provides other information on the block. The bits in the tag byte have these meanings:
Bit |
Meaning |
---|---|
In the tag byte, the high-order 2 bits determine whether a block is free (binary 00), relocatable (binary 10), or nonrelocatable (binary 01). The low-order 4 bits contain a block's size correction, the number of unused bytes at the end of the block, beyond the end of the block's contents. This correction is equal to the difference between the block's logical and physical sizes, excluding the 8 bytes of overhead for the block header, as in the following formula:
physicalSize = logicalSize + sizeCorrection + 8
The contents of the second long word (4 bytes) in the 24-bit block header depend on the type of block. For relocatable blocks, the second long word contains the block's relative handle: a pointer to the block's master pointer, expressed as an offset relative to the start of the heap zone rather than as an absolute memory address. Adding the relative handle to the zone pointer produces a true handle for this block. For nonrelocatable blocks, the second long word of the header is just a pointer to the block's zone. For free blocks, the contents of these 4 bytes are undefined.
In a 32-bit zone, a block header consists of 12 bytes, which together make up three long words, as shown in Figure 2 .
Figure 2 A block header in a 32-bit zone
The first byte of the block header is a tag byte that indicates the type of the block. The bits in the tag byte have these meanings:
Bit |
Meaning |
---|---|
In the tag byte, the high-order 2 bits determine whether a block is free (binary 00), relocatable (binary 10), or nonrelocatable (binary 01).
The second byte in the block header contains the master pointer flag bits, if the block is a relocatable block. Otherwise, this byte is undefined. The bits in this byte have these meanings:
Bit |
Meaning |
---|---|
The low-order byte of the high-order long word contains the block's size correction. This correction is equal to the difference between the block's logical and physical sizes, excluding the 12 bytes of overhead for the block header, as follows:
physicalSize = logicalSize + sizeCorrection + 12
The second long word in the 32-bit block header contains the block's physical size, and the third long word contains the block's relative handle. These fields have the same meaning as the corresponding fields in the 24-bit block header.